package Meta

import (
	"errors"
	"fmt"
	"reflect"
)

func (ma Meta) objectName() map[string]reflect.Value {
	return map[string]reflect.Value{
		"table":     reflect.ValueOf(ma.tableName),
		"job":       reflect.ValueOf(ma.jobName),
		"view":      reflect.ValueOf(ma.viewName),
		"mview":     reflect.ValueOf(ma.mViewName),
		"seq":       reflect.ValueOf(ma.seqName),
		"trigger":   reflect.ValueOf(ma.triggerName),
		"foreign":   reflect.ValueOf(ma.foreignName),
		"type":      reflect.ValueOf(ma.typeName),
		"func":      reflect.ValueOf(ma.funcName),
		"procedure": reflect.ValueOf(ma.procedureName),
		"package":   reflect.ValueOf(ma.packageName),
	}
}
func (ma Meta) objectExist() map[string]reflect.Value {
	return map[string]reflect.Value{
		"table":     reflect.ValueOf(ma.tableExistence),
		"job":       reflect.ValueOf(ma.jobExistence),
		"view":      reflect.ValueOf(ma.viewExistence),
		"mview":     reflect.ValueOf(ma.mViewExistence),
		"seq":       reflect.ValueOf(ma.seqExistence),
		"trigger":   reflect.ValueOf(ma.triggerExistence),
		"foreign":   reflect.ValueOf(ma.foreignExistence),
		"type":      reflect.ValueOf(ma.typeExistence),
		"func":      reflect.ValueOf(ma.funcExistence),
		"procedure": reflect.ValueOf(ma.procedureExistence),
		"package":   reflect.ValueOf(ma.packageExistence),
	}
}
func (ma Meta) ddlObjectDrop() map[string]reflect.Value {
	return map[string]reflect.Value{
		"table":    reflect.ValueOf(ma.tableDrop),
		"rename":   reflect.ValueOf(ma.tableRename),
		"recover":  reflect.ValueOf(ma.tableRecover),
		"truncate": reflect.ValueOf(ma.tableTruncate),
		"analyze":  reflect.ValueOf(ma.tableAnalyze),
		//"job":       reflect.ValueOf(ma.jobExistence),
		"view":  reflect.ValueOf(ma.viewDrop),
		"mview": reflect.ValueOf(ma.mViewDrop),
		"seq":   reflect.ValueOf(ma.seqDrop),
		//"trigger":   reflect.ValueOf(ma.triggerExistence),
		//"foreign":   reflect.ValueOf(ma.foreignExistence),
		//"type":      reflect.ValueOf(ma.typeExistence),
		//"func":      reflect.ValueOf(ma.funcExistence),
		//"procedure": reflect.ValueOf(ma.procedureExistence),
		//"package":   reflect.ValueOf(ma.packageExistence),
	}
}

func (ma Meta) execDDLObject() map[string]reflect.Value {
	return map[string]reflect.Value{
		"table": reflect.ValueOf(ma.execDDL),
		//"job":       reflect.ValueOf(ma.jobExistence),
		//"view":      reflect.ValueOf(ma.viewDrop),
		//"mview":     reflect.ValueOf(ma.mViewDrop),
		"seq": reflect.ValueOf(ma.execDDL),
		//"trigger":   reflect.ValueOf(ma.triggerExistence),
		//"foreign":   reflect.ValueOf(ma.foreignExistence),
		//"type":      reflect.ValueOf(ma.typeExistence),
		//"func":      reflect.ValueOf(ma.funcExistence),
		//"procedure": reflect.ValueOf(ma.procedureExistence),
		//"package":   reflect.ValueOf(ma.packageExistence),
	}
}
func NewMeta(drive []string, join, role string) *Meta {
	return &Meta{Drive: drive, Role: role, Join: join}
}
func (ma Meta) GetObjectName() (newResult []string, newErr error) {
	Func, ok := ma.objectName()[ma.Role]
	if !ok {
		return
	}
	res := Func.Call(nil)
	result, err := res[0].Interface(), res[1].Interface()
	if result != nil {
		newResult = result.([]string)
	}
	if err != nil {
		newErr = err.(error)
	}
	return
}
func (ma Meta) GetObjectExistence() (newResult bool, newErr error) {
	Func, ok := ma.objectExist()[ma.Role]
	if !ok {
		newErr = errors.New(fmt.Sprintf("The input role failed. role is %v", ma.Role))
		return
	}
	res := Func.Call(nil)
	result, err := res[0].Interface(), res[1].Interface()
	if err != nil {
		newErr = err.(error)
	}
	var existenceG []bool
	switch result.(type) {
	case []any:
		for _, v := range result.([]any) {
			switch v.(type) {
			case bool:
				existenceG = append(existenceG, v.(bool))
			}
		}
	case any:
		existenceG = append(existenceG, result.(bool))
	}
	for k, v := range existenceG {
		if k == 0 && v {
			newResult = true
		}
		if k == 1 && newResult && !v {
			newResult = false
		}
	}
	return
}
func (ma Meta) DDLObjectDrop() (newErr error) {
	Func, ok := ma.ddlObjectDrop()[ma.Role]
	if !ok {
		return
	}
	res := Func.Call(nil)
	err := res[1].Interface()
	if err != nil {
		newErr = err.(error)
	}
	return
}

func (ma Meta) ExecDDLObject() (newErr error) {
	Func, ok := ma.execDDLObject()[ma.Role]
	if !ok {
		return
	}
	res := Func.Call(nil)
	err := res[1].Interface()
	if err != nil {
		newErr = err.(error)
	}
	return
}
